export type t<T> = IteratorResult<() => t<T>, T>

export const fn
  : <A extends unknown[], R>(f: (...args: A) => t<R>) => (...args: A) => t<R>
  = f => (...args) => ({
    done: false,
    value: () => f(...args),
  })

export const of
  : <T>(value: T) => t<T>
  = value => ({ done: true, value })

export const run
  : <T>(t: t<T>) => T
  = t => {
    while (!t.done) t = t.value()
    return t.value
  }
